﻿namespace OboutInc
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.IO;
    using System.Threading;
    using System.Web.UI;

    [ParseChildren(true), ToolboxBitmap(typeof(CallbackPanel), "icon_2.bmp"), PersistChildren(false)]
    public class CallbackPanel : Control
    {
        private CallbackPanelContent _content;
        private CallbackPanelLoading _loading;
        internal bool DesignMode;
        private bool needs_update;
        private CallbackPanelRenderMethod renderMethod;
        private bool showLoading = true;
        private bool update_canceled;
        private string update_in;

        public event OnBeforePanelUpdate BeforePanelUpdate;

        public event OnPanelUpdate PanelUpdate;

        public CallbackPanel()
        {
            this.update_in = this.ClientID;
            this.DesignMode = LicenseManager.UsageMode == LicenseUsageMode.Designtime;
        }

        private IAJAX GetContainerPage()
        {
            IAJAX page = null;
            try
            {
                page = (IAJAX) this.Page;
            }
            catch (InvalidCastException)
            {
                throw new Exception("Your page need to inherit from OboutInc.oboutAJAXPage class.");
            }
            if (page == null)
            {
                page = (IAJAX) this.Page;
            }
            return page;
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
        }

        private void RegisterForEventValidation(Control ctrl)
        {
            foreach (Control control in ctrl.Controls)
            {
                this.RegisterForEventValidation(control);
                this.Page.ClientScript.RegisterForEventValidation(control.UniqueID);
                this.Page.ClientScript.RegisterForEventValidation(control.ID);
                this.Page.ClientScript.RegisterForEventValidation(control.ClientID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.UniqueID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.ID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.ClientID);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            this.RegisterForEventValidation(this);
            if (this.DesignMode)
            {
                base.Render(writer);
            }
            else
            {
                if ((this.ID == string.Empty) && !this.DesignMode)
                {
                    throw new Exception("The ID cannot be null.");
                }
                if (!(this.Page is oboutAJAXPage))
                {
                    throw new Exception("CallbackPanel can only be placed inside an Obout AJAX page. Make sure your page inherits oboutAJAXPage.");
                }
                IAJAX containerPage = this.GetContainerPage();
                if (((this.renderMethod != CallbackPanelRenderMethod.OnExplicitRequestAndPageLoad) && !containerPage.IsCallback) && (this.renderMethod != CallbackPanelRenderMethod.Always))
                {
                    this.RenderEmptyControl(writer);
                }
                if (this.ShouldRender())
                {
                    if (this.update_canceled)
                    {
                        ScriptResponse newScriptResponse = containerPage.GetNewScriptResponse(false);
                        newScriptResponse.WriteResponse(new object[] { "", "" });
                        newScriptResponse.WriteScript("ob_post_updatePanel(response.content,\"" + this.update_in + "\",false,false,req_id)");
                    }
                    else
                    {
                        StringWriter writer2 = new StringWriter();
                        HtmlTextWriter writer3 = new HtmlTextWriter(writer2);
                        if (!containerPage.IsCallback)
                        {
                            writer3.Write("<div " + ((this.RenderMethod == CallbackPanelRenderMethod.OnExplicitRequestAndPageLoad) ? " RenderWithAll=\"false\"" : "") + " id=\"" + this.ID + "\" ShowLoading=\"" + (this.ShowLoading ? "true" : "false") + "\"" + ((this.ClientOnUnload.Length > 0) ? (" onunload=\"" + this.ClientOnUnload + "\"") : "") + ">");
                        }
                        this.Content.RenderControl(writer3);
                        if (!containerPage.IsCallback)
                        {
                            if (this._loading == null)
                            {
                                this._loading = new CallbackPanelLoading_Default(this);
                                this.Controls.Add(this._loading);
                                IEnumerator enumerator = this.Content.Style.Keys.GetEnumerator();
                                while (enumerator.MoveNext())
                                {
                                    this._loading.Style[enumerator.Current.ToString().ToLower().Trim()] = this.Content.Style[enumerator.Current.ToString()];
                                }
                            }
                            this.Loading.RenderControl(writer3);
                            writer3.Write("</div>");
                        }
                        writer3.Flush();
                        string content = writer2.ToString();
                        if (containerPage.IsCallback)
                        {
                            content = content.Replace("\r\n", "").Replace("\t", "").Replace("\r", "").Replace("\n", "");
                            object obj2 = containerPage.parseForElements(content, true, true);
                            ScriptResponse response2 = containerPage.GetNewScriptResponse(false);
                            response2.WriteResponse(obj2);
                            response2.WriteScript("ob_post_updatePanel(response.content,\"" + this.update_in + "\",true,true,req_id)");
                            if (this.needs_update && (this.PanelUpdate != null))
                            {
                                this.PanelUpdate(this.ID, this.update_in);
                            }
                        }
                        else
                        {
                            writer.Write(content);
                            writer.Write("<script language=\"javascript\">ob_post.RegisterPanel(\"" + this.ID + "\");</script>");
                        }
                    }
                }
            }
        }

        private void RenderEmptyControl(HtmlTextWriter writer)
        {
            StringWriter writer2 = new StringWriter();
            HtmlTextWriter writer3 = new HtmlTextWriter(writer2);
            writer3.Write("<div id=\"" + this.ID + "\"" + ((this.RenderMethod == CallbackPanelRenderMethod.OnExplicitRequest) ? " RenderWithAll=\"false\"" : "") + ">");
            this.Content.Style.Add("display", "none");
            this.Content.RenderEmpty(writer3);
            if (this._loading == null)
            {
                this._loading = new CallbackPanelLoading_Default(this);
                this.Controls.Add(this._loading);
                IEnumerator enumerator = this.Content.Style.Keys.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    this._loading.Style[enumerator.Current.ToString().ToLower().Trim()] = this.Content.Style[enumerator.Current.ToString()];
                }
            }
            this.Loading.RenderControl(writer3);
            writer3.Write("</div>");
            writer3.Flush();
            writer.Write(writer2.ToString());
            writer.Write("<script language=\"javascript\">ob_post.RegisterPanel(\"" + this.ID + "\");</script>");
        }

        private bool ShouldRender()
        {
            IAJAX containerPage = this.GetContainerPage();
            if ((!containerPage.IsCallback && (this.renderMethod != CallbackPanelRenderMethod.Always)) && (this.renderMethod != CallbackPanelRenderMethod.OnExplicitRequestAndPageLoad))
            {
                return false;
            }
            if ((containerPage.IsCallback && ((this.renderMethod == CallbackPanelRenderMethod.OnExplicitRequest) || (this.renderMethod == CallbackPanelRenderMethod.OnExplicitRequestAndPageLoad))) && containerPage.IsUpdateAllPanels)
            {
                return false;
            }
            if (containerPage.IsCallback && !this.needs_update)
            {
                return false;
            }
            return true;
        }

        public void Update()
        {
            this.update_in = this.ID;
            if ((this.BeforePanelUpdate != null) && !this.BeforePanelUpdate(this.ID, this.update_in))
            {
                this.update_canceled = true;
            }
            this.needs_update = true;
        }

        public void UpdateIn(string containerID)
        {
            this.update_in = containerID;
            if ((this.BeforePanelUpdate != null) && !this.BeforePanelUpdate(this.ID, this.update_in))
            {
                this.update_canceled = true;
            }
            this.needs_update = true;
        }

        public string ClientOnUnload
        {
            get
            {
                if (this.ViewState["ClientOnUnload"] == null)
                {
                    return "";
                }
                return this.ViewState["ClientOnUnload"].ToString();
            }
            set
            {
                this.ViewState["ClientOnUnload"] = value;
            }
        }

        [Browsable(false)]
        public string ComponentVersion
        {
            get
            {
                if (this.Page is oboutAJAXPage)
                {
                    oboutAJAXPage page = (oboutAJAXPage) this.Page;
                    return page.ComponentVersion;
                }
                return "<br />(Not inside an OboutPage)";
            }
        }

        [PersistenceMode(PersistenceMode.InnerProperty), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("The content of this CallbackPanel."), NotifyParentProperty(true)]
        public CallbackPanelContent Content
        {
            get
            {
                if (this._content == null)
                {
                    this._content = new CallbackPanelContent(this);
                    this.Controls.Add(this._content);
                }
                return this._content;
            }
        }

        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty), NotifyParentProperty(true), Description("The content of this CallbackPanel while the panel is updating."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public CallbackPanelLoading Loading
        {
            get
            {
                if (this._loading == null)
                {
                    this._loading = new CallbackPanelLoading(this);
                    this.Controls.Add(this._loading);
                }
                return this._loading;
            }
        }

        [DefaultValue(0), Description("When should this panel be rendered.")]
        public CallbackPanelRenderMethod RenderMethod
        {
            get
            {
                return this.renderMethod;
            }
            set
            {
                this.renderMethod = value;
            }
        }

        [Description("If to show or not the loading panel after callback on button postback."), DefaultValue(true)]
        public bool ShowLoading
        {
            get
            {
                return this.showLoading;
            }
            set
            {
                this.showLoading = value;
            }
        }
    }
}

